/**
 * 
 */
package io.dora.registry;

import io.dora.base.Synchronizer;
import io.dora.remoting.ConsumerClient;

import java.net.InetAddress;
import java.net.Socket;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 服务同步器实现
 *
 * @author zhaohongbo
 *
 */
public class ServiceSynchronizer extends TimerTask implements Synchronizer {
	
	private Logger logger = LoggerFactory.getLogger(ServiceSynchronizer.class);

	/** 服务KEY对应的服务消费端 */
	private Map<String, ConsumerClient> consumerClientMap;

	/** 异常消费端 */
	private Set<ConsumerClient> errorConsumerSet = new HashSet<ConsumerClient>();
	
	private static Synchronizer instance = null;

	private ServiceSynchronizer() {
		
	}

	@Override
	public void start() {
		Timer timer = new Timer(); 
        timer.schedule(this, 10000, 20000);
	}

	@Override
	public void run() {
		
		if (consumerClientMap == null) {
			return;
		}
		
		for (Map.Entry<String, ConsumerClient> entry : consumerClientMap.entrySet()) {
			
			try {
				logger.info("Detection for: {}", entry.getValue().getAddress());
				InetAddress theAddress = InetAddress.getByName(entry.getValue().getHost());
				new Socket(theAddress, entry.getValue().getPort());
			} catch (Exception e) {
				entry.getValue().setSuccess(false);
				errorConsumerSet.add(entry.getValue());
				consumerClientMap.remove(entry.getKey());
				logger.info("Host:{} fail.", entry.getValue().getAddress());
			}
		}
		
		for (ConsumerClient consumerClient : errorConsumerSet) {
			try {
				logger.info("Detection for:{}", consumerClient.getAddress());
				InetAddress theAddress = InetAddress.getByName(consumerClient.getHost());
				new Socket(theAddress, consumerClient.getPort());
				consumerClient.setSuccess(true);
			} catch (Exception e) {
				logger.info("Host:{} fail.", consumerClient.getAddress());
			}
		}
	}

	public static Synchronizer get() {
		if (instance == null) {
			instance = new ServiceSynchronizer();
		}
		return instance;
	}

	@Override
	public void init(Map<String, ConsumerClient> consumerClientMap) {
		this.consumerClientMap = consumerClientMap;
	}

}
